package com.borened.common.boot.interceptor;


import cn.hutool.core.util.StrUtil;
import com.borened.common.boot.security.SecurityContextHolder;
import com.borened.common.core.constant.SecurityConstants;
import com.borened.common.core.security.InnerAuth;
import com.borened.common.core.security.RequestSource;
import com.borened.common.core.util.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.AsyncHandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 自定义请求头拦截器，将Header数据封装到线程变量中方便获取
 *
 * @author cch
 */
@Slf4j
public class AsyncRequestHeaderInterceptor implements AsyncHandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        InnerAuth innerAuth = handlerMethod.getMethodAnnotation(InnerAuth.class);
        if (innerAuth != null && !innerAuth.checkToken()) {
            String requestSource = request.getHeader(SecurityConstants.REQUEST_SOURCE);
            //确认是内部认证调用 则跳过token认证检查。
            if (StrUtil.equalsIgnoreCase(requestSource, RequestSource.INNER.getValue())) {
                return true;
            }
        }
        //设置请求头参数到线程上下文，异步情况下传递参数. jwt payload信息到线程安全上下文
        SecurityContextHolder.setLocalMap(new ConcurrentHashMap<>(JwtUtils.getJwtPayload()));
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        SecurityContextHolder.remove();
    }
}
